package com.mini.auth.config;

import com.mini.auth.details.OAuthUserDetails;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import java.security.KeyPair;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * jwt的相关配置
 * @author Zhou Feng
 */
@Configuration
public class JwtConfig {

    /**
     * 使用jwt，不存储token
     */
    @Bean("jwtStore")
    public JwtTokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 将生成的access_token转为JwtToken
     */
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        //设置jwt密钥对,非对称加密
        converter.setKeyPair(keyPair());
        return converter;
    }

    /**
     * 从classpath下的密钥库中获取密钥对(公钥+私钥)
     */
    public KeyPair keyPair() {
        KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray());
        return factory.getKeyPair("jwt", "123456".toCharArray());
    }

    /**
     * 扩展jwt中的内容
     */
    public TokenEnhancer extendJwt(){
        return (accessToken,auth2Authentication) -> {
            Authentication authentication = auth2Authentication.getUserAuthentication();
            OAuthUserDetails user = (OAuthUserDetails) authentication.getPrincipal();
            HashMap<String, Object> map = new HashMap<>();
            map.put("username", user.getUsername());
            map.put("nickname", user.getNickname());
            map.put("uid", user.getId());
            ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(map);
            return accessToken;
        };
    }

    /**
     * 将最终的TokenEnhancer注入容器
     */
    @Bean
    public TokenEnhancer tokenEnhancer(){
        //要添加TokenEnhancerChain配置才可以生成jwt
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        ArrayList<TokenEnhancer> enhancers = new ArrayList<>();
        enhancers.add(extendJwt());
        enhancers.add(jwtAccessTokenConverter());
        enhancerChain.setTokenEnhancers(enhancers);
        return enhancerChain;
    }
}
